using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Xml;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Xml.Xsl;

namespace Adoor.Wizard
{
    /// <summary>
    /// Summary description for FormWizard.
    /// </summary>
    public class FormWizard : System.Windows.Forms.Form, Adoor.Metadata.IXmlWriterProvider
    {
        private System.Windows.Forms.Panel panelBottom;
        private System.Windows.Forms.Panel panelTop;
        private System.Windows.Forms.Panel panelBody;
        private System.Windows.Forms.Button buttonPrev;
        private System.Windows.Forms.Button buttonNext;
        private System.Windows.Forms.TabControl tabControl1;
        private System.Windows.Forms.TabPage tabPage1;
        private System.Windows.Forms.TabPage tabPage2;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Button buttonLoadProject;
        private System.Windows.Forms.TextBox textBoxXmiFilePath;
        private System.Windows.Forms.Button buttonSelectInputXMI;
        private DataSet dsProject;

        private Node xmiNode;
        private Node mappingsNode;
        private Node codeNode;
        private Node dbNode;

        private string CSharpInput;
        private string MySqlInput;
        private string MsSqlInput;
        private string MapInput;
        private string XMIInput;
        private string DBInput;

        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;
        private int selectedTabIndex;
        private bool stepsReady;

        private string outputPath = "";
        private System.Windows.Forms.Panel panel1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.DataGrid dataGridUMDDataTypes;
        private System.Windows.Forms.TabPage tabPage3;
        private System.Windows.Forms.TabPage tabPage4;
        private System.Windows.Forms.TabPage tabPage5;
        private System.Windows.Forms.TabPage tabPage6;
        private System.Windows.Forms.TabControl tabControlMapping;
        private System.Windows.Forms.DataGrid dataGridCodeValues;
        private System.Windows.Forms.DataGrid dataGridDBValues;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Label labelGenerating;
        private System.Windows.Forms.Button buttonSave;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.TextBox textBoxOutput;
        private System.Windows.Forms.Button buttonChooseOutput;
        private System.Windows.Forms.RadioButton radioButtonMsSql;
        private System.Windows.Forms.RadioButton radioButtonMySql;
        private System.Windows.Forms.Panel panel2;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.Panel panel3;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Panel panel4;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.Button buttonExit;
        private System.Windows.Forms.Button buttonUpdateIds;
        private System.Windows.Forms.TabPage tabPage7;
        private System.Windows.Forms.CheckBox checkBoxCode;
        private System.Windows.Forms.CheckBox checkBoxDatabase;
        private System.Windows.Forms.CheckBox checkBoxMapping;
        private System.Windows.Forms.StatusBar statusBar1;
        private FormResults results;
        private ProgressBar pgBar = new ProgressBar();


        public FormWizard()
        {
            //
            // Required for Windows Form Designer support
            //
            stepsReady = false;
            InitializeComponent();

            tabControl1.ItemSize = new Size(1, 1);
            tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
            selectedTabIndex = 0;
            stepsReady = true;

            dsProject = new DataSet();

            results = new FormResults();
            textBoxOutput.Text = System.Configuration.ConfigurationManager.AppSettings["defautOuputFolder"];
            CSharpInput = System.Configuration.ConfigurationManager.AppSettings["CSharpInput"];
            MySqlInput = System.Configuration.ConfigurationManager.AppSettings["MySqlInput"];
            MsSqlInput = System.Configuration.ConfigurationManager.AppSettings["MsSqlInput"];
            MapInput = System.Configuration.ConfigurationManager.AppSettings["MapInput"];
            XMIInput = System.Configuration.ConfigurationManager.AppSettings["XMIInput"];


            foreach (System.Reflection.AssemblyName assName in typeof(FormWizard).Assembly.GetReferencedAssemblies())
            {
                AppDomain.CurrentDomain.Load(assName);
            }

            xmiNode = new Node();
            mappingsNode = new Node();
            codeNode = new Node();
            dbNode = new Node();

            currentNode = xmiNode;
            DBInput = MsSqlInput;

            pgBar.Dock = DockStyle.Right;
            pgBar.Width = 100;

            statusBar1.Controls.Add(pgBar);
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.panelBottom = new System.Windows.Forms.Panel();
            this.buttonSave = new System.Windows.Forms.Button();
            this.buttonNext = new System.Windows.Forms.Button();
            this.buttonPrev = new System.Windows.Forms.Button();
            this.buttonExit = new System.Windows.Forms.Button();
            this.panelTop = new System.Windows.Forms.Panel();
            this.panelBody = new System.Windows.Forms.Panel();
            this.tabControl1 = new System.Windows.Forms.TabControl();
            this.tabPage1 = new System.Windows.Forms.TabPage();
            this.buttonChooseOutput = new System.Windows.Forms.Button();
            this.textBoxOutput = new System.Windows.Forms.TextBox();
            this.label3 = new System.Windows.Forms.Label();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.radioButtonMySql = new System.Windows.Forms.RadioButton();
            this.radioButtonMsSql = new System.Windows.Forms.RadioButton();
            this.buttonSelectInputXMI = new System.Windows.Forms.Button();
            this.textBoxXmiFilePath = new System.Windows.Forms.TextBox();
            this.buttonLoadProject = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.tabPage2 = new System.Windows.Forms.TabPage();
            this.dataGridUMDDataTypes = new System.Windows.Forms.DataGrid();
            this.panel1 = new System.Windows.Forms.Panel();
            this.label2 = new System.Windows.Forms.Label();
            this.tabPage3 = new System.Windows.Forms.TabPage();
            this.tabControlMapping = new System.Windows.Forms.TabControl();
            this.panel2 = new System.Windows.Forms.Panel();
            this.buttonUpdateIds = new System.Windows.Forms.Button();
            this.label4 = new System.Windows.Forms.Label();
            this.tabPage4 = new System.Windows.Forms.TabPage();
            this.dataGridCodeValues = new System.Windows.Forms.DataGrid();
            this.panel3 = new System.Windows.Forms.Panel();
            this.label5 = new System.Windows.Forms.Label();
            this.tabPage5 = new System.Windows.Forms.TabPage();
            this.dataGridDBValues = new System.Windows.Forms.DataGrid();
            this.panel4 = new System.Windows.Forms.Panel();
            this.label6 = new System.Windows.Forms.Label();
            this.tabPage7 = new System.Windows.Forms.TabPage();
            this.checkBoxMapping = new System.Windows.Forms.CheckBox();
            this.checkBoxDatabase = new System.Windows.Forms.CheckBox();
            this.checkBoxCode = new System.Windows.Forms.CheckBox();
            this.tabPage6 = new System.Windows.Forms.TabPage();
            this.button1 = new System.Windows.Forms.Button();
            this.labelGenerating = new System.Windows.Forms.Label();
            this.statusBar1 = new System.Windows.Forms.StatusBar();
            this.panelBottom.SuspendLayout();
            this.panelBody.SuspendLayout();
            this.tabControl1.SuspendLayout();
            this.tabPage1.SuspendLayout();
            this.groupBox1.SuspendLayout();
            this.tabPage2.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridUMDDataTypes)).BeginInit();
            this.panel1.SuspendLayout();
            this.tabPage3.SuspendLayout();
            this.panel2.SuspendLayout();
            this.tabPage4.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridCodeValues)).BeginInit();
            this.panel3.SuspendLayout();
            this.tabPage5.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridDBValues)).BeginInit();
            this.panel4.SuspendLayout();
            this.tabPage7.SuspendLayout();
            this.tabPage6.SuspendLayout();
            this.SuspendLayout();
            // 
            // panelBottom
            // 
            this.panelBottom.Controls.Add(this.buttonSave);
            this.panelBottom.Controls.Add(this.buttonNext);
            this.panelBottom.Controls.Add(this.buttonPrev);
            this.panelBottom.Controls.Add(this.buttonExit);
            this.panelBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.panelBottom.Location = new System.Drawing.Point(0, 415);
            this.panelBottom.Name = "panelBottom";
            this.panelBottom.Padding = new System.Windows.Forms.Padding(5, 7, 20, 7);
            this.panelBottom.Size = new System.Drawing.Size(608, 40);
            this.panelBottom.TabIndex = 0;
            // 
            // buttonSave
            // 
            this.buttonSave.Location = new System.Drawing.Point(16, 8);
            this.buttonSave.Name = "buttonSave";
            this.buttonSave.Size = new System.Drawing.Size(96, 24);
            this.buttonSave.TabIndex = 3;
            this.buttonSave.Text = "Save project";
            this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click);
            // 
            // buttonNext
            // 
            this.buttonNext.Location = new System.Drawing.Point(256, 8);
            this.buttonNext.Name = "buttonNext";
            this.buttonNext.Size = new System.Drawing.Size(75, 23);
            this.buttonNext.TabIndex = 2;
            this.buttonNext.Text = "Next";
            this.buttonNext.Click += new System.EventHandler(this.buttonNext_Click);
            // 
            // buttonPrev
            // 
            this.buttonPrev.Location = new System.Drawing.Point(168, 8);
            this.buttonPrev.Name = "buttonPrev";
            this.buttonPrev.Size = new System.Drawing.Size(75, 23);
            this.buttonPrev.TabIndex = 1;
            this.buttonPrev.Text = "Prev";
            this.buttonPrev.Click += new System.EventHandler(this.buttonPrev_Click);
            // 
            // buttonExit
            // 
            this.buttonExit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.buttonExit.Location = new System.Drawing.Point(512, 8);
            this.buttonExit.Name = "buttonExit";
            this.buttonExit.Size = new System.Drawing.Size(75, 23);
            this.buttonExit.TabIndex = 0;
            this.buttonExit.Text = "Exit";
            this.buttonExit.Click += new System.EventHandler(this.buttonExit_Click);
            // 
            // panelTop
            // 
            this.panelTop.Dock = System.Windows.Forms.DockStyle.Top;
            this.panelTop.Location = new System.Drawing.Point(0, 0);
            this.panelTop.Name = "panelTop";
            this.panelTop.Size = new System.Drawing.Size(608, 48);
            this.panelTop.TabIndex = 1;
            // 
            // panelBody
            // 
            this.panelBody.Controls.Add(this.tabControl1);
            this.panelBody.Dock = System.Windows.Forms.DockStyle.Fill;
            this.panelBody.Location = new System.Drawing.Point(0, 48);
            this.panelBody.Name = "panelBody";
            this.panelBody.Size = new System.Drawing.Size(608, 367);
            this.panelBody.TabIndex = 2;
            // 
            // tabControl1
            // 
            this.tabControl1.Appearance = System.Windows.Forms.TabAppearance.FlatButtons;
            this.tabControl1.Controls.Add(this.tabPage1);
            this.tabControl1.Controls.Add(this.tabPage2);
            this.tabControl1.Controls.Add(this.tabPage3);
            this.tabControl1.Controls.Add(this.tabPage4);
            this.tabControl1.Controls.Add(this.tabPage5);
            this.tabControl1.Controls.Add(this.tabPage7);
            this.tabControl1.Controls.Add(this.tabPage6);
            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tabControl1.ItemSize = new System.Drawing.Size(42, 0);
            this.tabControl1.Location = new System.Drawing.Point(0, 0);
            this.tabControl1.Name = "tabControl1";
            this.tabControl1.SelectedIndex = 0;
            this.tabControl1.Size = new System.Drawing.Size(608, 367);
            this.tabControl1.SizeMode = System.Windows.Forms.TabSizeMode.FillToRight;
            this.tabControl1.TabIndex = 0;
            this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabControl1_SelectedIndexChanged);
            // 
            // tabPage1
            // 
            this.tabPage1.Controls.Add(this.buttonChooseOutput);
            this.tabPage1.Controls.Add(this.textBoxOutput);
            this.tabPage1.Controls.Add(this.label3);
            this.tabPage1.Controls.Add(this.groupBox1);
            this.tabPage1.Controls.Add(this.buttonSelectInputXMI);
            this.tabPage1.Controls.Add(this.textBoxXmiFilePath);
            this.tabPage1.Controls.Add(this.buttonLoadProject);
            this.tabPage1.Controls.Add(this.label1);
            this.tabPage1.Location = new System.Drawing.Point(4, 25);
            this.tabPage1.Name = "tabPage1";
            this.tabPage1.Size = new System.Drawing.Size(600, 338);
            this.tabPage1.TabIndex = 0;
            this.tabPage1.Text = "Init";
            // 
            // buttonChooseOutput
            // 
            this.buttonChooseOutput.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.buttonChooseOutput.Location = new System.Drawing.Point(568, 80);
            this.buttonChooseOutput.Name = "buttonChooseOutput";
            this.buttonChooseOutput.Size = new System.Drawing.Size(24, 20);
            this.buttonChooseOutput.TabIndex = 7;
            this.buttonChooseOutput.Text = "...";
            this.buttonChooseOutput.Click += new System.EventHandler(this.buttonChooseOutput_Click);
            // 
            // textBoxOutput
            // 
            this.textBoxOutput.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.textBoxOutput.Location = new System.Drawing.Point(136, 80);
            this.textBoxOutput.Name = "textBoxOutput";
            this.textBoxOutput.Size = new System.Drawing.Size(432, 20);
            this.textBoxOutput.TabIndex = 6;
            this.textBoxOutput.TextChanged += new System.EventHandler(this.textBoxOutput_TextChanged);
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(16, 82);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(69, 13);
            this.label3.TabIndex = 5;
            this.label3.Text = "Output path :";
            // 
            // groupBox1
            // 
            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBox1.Controls.Add(this.radioButtonMySql);
            this.groupBox1.Controls.Add(this.radioButtonMsSql);
            this.groupBox1.Location = new System.Drawing.Point(8, 104);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(584, 48);
            this.groupBox1.TabIndex = 4;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Database type";
            // 
            // radioButtonMySql
            // 
            this.radioButtonMySql.Location = new System.Drawing.Point(152, 16);
            this.radioButtonMySql.Name = "radioButtonMySql";
            this.radioButtonMySql.Size = new System.Drawing.Size(104, 24);
            this.radioButtonMySql.TabIndex = 1;
            this.radioButtonMySql.Text = "MySql";
            // 
            // radioButtonMsSql
            // 
            this.radioButtonMsSql.Checked = true;
            this.radioButtonMsSql.Location = new System.Drawing.Point(32, 16);
            this.radioButtonMsSql.Name = "radioButtonMsSql";
            this.radioButtonMsSql.Size = new System.Drawing.Size(104, 24);
            this.radioButtonMsSql.TabIndex = 0;
            this.radioButtonMsSql.TabStop = true;
            this.radioButtonMsSql.Text = "MsSql Server";
            // 
            // buttonSelectInputXMI
            // 
            this.buttonSelectInputXMI.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.buttonSelectInputXMI.Location = new System.Drawing.Point(568, 46);
            this.buttonSelectInputXMI.Name = "buttonSelectInputXMI";
            this.buttonSelectInputXMI.Size = new System.Drawing.Size(24, 20);
            this.buttonSelectInputXMI.TabIndex = 3;
            this.buttonSelectInputXMI.Text = "...";
            this.buttonSelectInputXMI.Click += new System.EventHandler(this.buttonSelectInputXMI_Click);
            // 
            // textBoxXmiFilePath
            // 
            this.textBoxXmiFilePath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.textBoxXmiFilePath.Location = new System.Drawing.Point(136, 46);
            this.textBoxXmiFilePath.Name = "textBoxXmiFilePath";
            this.textBoxXmiFilePath.Size = new System.Drawing.Size(432, 20);
            this.textBoxXmiFilePath.TabIndex = 2;
            // 
            // buttonLoadProject
            // 
            this.buttonLoadProject.Location = new System.Drawing.Point(16, 8);
            this.buttonLoadProject.Name = "buttonLoadProject";
            this.buttonLoadProject.Size = new System.Drawing.Size(88, 24);
            this.buttonLoadProject.TabIndex = 1;
            this.buttonLoadProject.Text = "Load Project";
            this.buttonLoadProject.Click += new System.EventHandler(this.buttonLoadProject_Click);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(16, 48);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(103, 13);
            this.label1.TabIndex = 0;
            this.label1.Text = "Select xmi input file :";
            // 
            // tabPage2
            // 
            this.tabPage2.Controls.Add(this.dataGridUMDDataTypes);
            this.tabPage2.Controls.Add(this.panel1);
            this.tabPage2.Location = new System.Drawing.Point(4, 25);
            this.tabPage2.Name = "tabPage2";
            this.tabPage2.Size = new System.Drawing.Size(600, 338);
            this.tabPage2.TabIndex = 1;
            this.tabPage2.Text = "Uml data mapping";
            // 
            // dataGridUMDDataTypes
            // 
            this.dataGridUMDDataTypes.DataMember = "";
            this.dataGridUMDDataTypes.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridUMDDataTypes.HeaderForeColor = System.Drawing.SystemColors.ControlText;
            this.dataGridUMDDataTypes.Location = new System.Drawing.Point(0, 32);
            this.dataGridUMDDataTypes.Name = "dataGridUMDDataTypes";
            this.dataGridUMDDataTypes.Size = new System.Drawing.Size(600, 306);
            this.dataGridUMDDataTypes.TabIndex = 1;
            // 
            // panel1
            // 
            this.panel1.Controls.Add(this.label2);
            this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
            this.panel1.Location = new System.Drawing.Point(0, 0);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(600, 32);
            this.panel1.TabIndex = 0;
            // 
            // label2
            // 
            this.label2.Location = new System.Drawing.Point(8, 8);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(136, 23);
            this.label2.TabIndex = 0;
            this.label2.Text = "UML Data types mapping";
            // 
            // tabPage3
            // 
            this.tabPage3.Controls.Add(this.tabControlMapping);
            this.tabPage3.Controls.Add(this.panel2);
            this.tabPage3.Location = new System.Drawing.Point(4, 25);
            this.tabPage3.Name = "tabPage3";
            this.tabPage3.Size = new System.Drawing.Size(600, 338);
            this.tabPage3.TabIndex = 2;
            this.tabPage3.Text = "Pivot Unique Ids";
            // 
            // tabControlMapping
            // 
            this.tabControlMapping.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tabControlMapping.Location = new System.Drawing.Point(0, 32);
            this.tabControlMapping.Name = "tabControlMapping";
            this.tabControlMapping.SelectedIndex = 0;
            this.tabControlMapping.Size = new System.Drawing.Size(600, 306);
            this.tabControlMapping.TabIndex = 0;
            // 
            // panel2
            // 
            this.panel2.Controls.Add(this.buttonUpdateIds);
            this.panel2.Controls.Add(this.label4);
            this.panel2.Dock = System.Windows.Forms.DockStyle.Top;
            this.panel2.Location = new System.Drawing.Point(0, 0);
            this.panel2.Name = "panel2";
            this.panel2.Size = new System.Drawing.Size(600, 32);
            this.panel2.TabIndex = 1;
            // 
            // buttonUpdateIds
            // 
            this.buttonUpdateIds.Location = new System.Drawing.Point(160, 7);
            this.buttonUpdateIds.Name = "buttonUpdateIds";
            this.buttonUpdateIds.Size = new System.Drawing.Size(80, 24);
            this.buttonUpdateIds.TabIndex = 1;
            this.buttonUpdateIds.Text = "Update UIDs";
            this.buttonUpdateIds.Click += new System.EventHandler(this.buttonUpdateIds_Click);
            // 
            // label4
            // 
            this.label4.Location = new System.Drawing.Point(8, 8);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(136, 23);
            this.label4.TabIndex = 0;
            this.label4.Text = "Class identifiers";
            // 
            // tabPage4
            // 
            this.tabPage4.Controls.Add(this.dataGridCodeValues);
            this.tabPage4.Controls.Add(this.panel3);
            this.tabPage4.Location = new System.Drawing.Point(4, 25);
            this.tabPage4.Name = "tabPage4";
            this.tabPage4.Size = new System.Drawing.Size(600, 338);
            this.tabPage4.TabIndex = 3;
            this.tabPage4.Text = "Code default values";
            // 
            // dataGridCodeValues
            // 
            this.dataGridCodeValues.DataMember = "";
            this.dataGridCodeValues.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridCodeValues.HeaderForeColor = System.Drawing.SystemColors.ControlText;
            this.dataGridCodeValues.Location = new System.Drawing.Point(0, 32);
            this.dataGridCodeValues.Name = "dataGridCodeValues";
            this.dataGridCodeValues.Size = new System.Drawing.Size(600, 306);
            this.dataGridCodeValues.TabIndex = 2;
            // 
            // panel3
            // 
            this.panel3.Controls.Add(this.label5);
            this.panel3.Dock = System.Windows.Forms.DockStyle.Top;
            this.panel3.Location = new System.Drawing.Point(0, 0);
            this.panel3.Name = "panel3";
            this.panel3.Size = new System.Drawing.Size(600, 32);
            this.panel3.TabIndex = 3;
            // 
            // label5
            // 
            this.label5.Location = new System.Drawing.Point(8, 8);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(136, 23);
            this.label5.TabIndex = 0;
            this.label5.Text = "C# default values";
            // 
            // tabPage5
            // 
            this.tabPage5.Controls.Add(this.dataGridDBValues);
            this.tabPage5.Controls.Add(this.panel4);
            this.tabPage5.Location = new System.Drawing.Point(4, 25);
            this.tabPage5.Name = "tabPage5";
            this.tabPage5.Size = new System.Drawing.Size(600, 338);
            this.tabPage5.TabIndex = 4;
            this.tabPage5.Text = "db Default values";
            // 
            // dataGridDBValues
            // 
            this.dataGridDBValues.DataMember = "";
            this.dataGridDBValues.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridDBValues.HeaderForeColor = System.Drawing.SystemColors.ControlText;
            this.dataGridDBValues.Location = new System.Drawing.Point(0, 32);
            this.dataGridDBValues.Name = "dataGridDBValues";
            this.dataGridDBValues.Size = new System.Drawing.Size(600, 306);
            this.dataGridDBValues.TabIndex = 2;
            // 
            // panel4
            // 
            this.panel4.Controls.Add(this.label6);
            this.panel4.Dock = System.Windows.Forms.DockStyle.Top;
            this.panel4.Location = new System.Drawing.Point(0, 0);
            this.panel4.Name = "panel4";
            this.panel4.Size = new System.Drawing.Size(600, 32);
            this.panel4.TabIndex = 4;
            // 
            // label6
            // 
            this.label6.Location = new System.Drawing.Point(8, 8);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(136, 23);
            this.label6.TabIndex = 0;
            this.label6.Text = "DB default values";
            // 
            // tabPage7
            // 
            this.tabPage7.Controls.Add(this.checkBoxMapping);
            this.tabPage7.Controls.Add(this.checkBoxDatabase);
            this.tabPage7.Controls.Add(this.checkBoxCode);
            this.tabPage7.Location = new System.Drawing.Point(4, 25);
            this.tabPage7.Name = "tabPage7";
            this.tabPage7.Size = new System.Drawing.Size(600, 338);
            this.tabPage7.TabIndex = 6;
            this.tabPage7.Text = "tabPageChoice";
            // 
            // checkBoxMapping
            // 
            this.checkBoxMapping.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.checkBoxMapping.Location = new System.Drawing.Point(40, 88);
            this.checkBoxMapping.Name = "checkBoxMapping";
            this.checkBoxMapping.Size = new System.Drawing.Size(176, 16);
            this.checkBoxMapping.TabIndex = 2;
            this.checkBoxMapping.Text = "Generate Mapping files";
            // 
            // checkBoxDatabase
            // 
            this.checkBoxDatabase.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.checkBoxDatabase.Location = new System.Drawing.Point(40, 56);
            this.checkBoxDatabase.Name = "checkBoxDatabase";
            this.checkBoxDatabase.Size = new System.Drawing.Size(176, 16);
            this.checkBoxDatabase.TabIndex = 1;
            this.checkBoxDatabase.Text = "Generate DB scripts";
            // 
            // checkBoxCode
            // 
            this.checkBoxCode.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
            this.checkBoxCode.Location = new System.Drawing.Point(40, 24);
            this.checkBoxCode.Name = "checkBoxCode";
            this.checkBoxCode.Size = new System.Drawing.Size(176, 16);
            this.checkBoxCode.TabIndex = 0;
            this.checkBoxCode.Text = "Generate code";
            // 
            // tabPage6
            // 
            this.tabPage6.Controls.Add(this.button1);
            this.tabPage6.Controls.Add(this.labelGenerating);
            this.tabPage6.Location = new System.Drawing.Point(4, 25);
            this.tabPage6.Name = "tabPage6";
            this.tabPage6.Size = new System.Drawing.Size(600, 338);
            this.tabPage6.TabIndex = 5;
            this.tabPage6.Text = "Generating";
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(16, 32);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(88, 24);
            this.button1.TabIndex = 1;
            this.button1.Text = "Display results";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // labelGenerating
            // 
            this.labelGenerating.Location = new System.Drawing.Point(16, 12);
            this.labelGenerating.Name = "labelGenerating";
            this.labelGenerating.Size = new System.Drawing.Size(136, 16);
            this.labelGenerating.TabIndex = 0;
            this.labelGenerating.Text = "Generating files ....";
            // 
            // statusBar1
            // 
            this.statusBar1.Location = new System.Drawing.Point(0, 455);
            this.statusBar1.Name = "statusBar1";
            this.statusBar1.Size = new System.Drawing.Size(608, 22);
            this.statusBar1.TabIndex = 3;
            // 
            // FormWizard
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(608, 477);
            this.Controls.Add(this.panelBody);
            this.Controls.Add(this.panelTop);
            this.Controls.Add(this.panelBottom);
            this.Controls.Add(this.statusBar1);
            this.Name = "FormWizard";
            this.Text = "Form1";
            this.panelBottom.ResumeLayout(false);
            this.panelBody.ResumeLayout(false);
            this.tabControl1.ResumeLayout(false);
            this.tabPage1.ResumeLayout(false);
            this.tabPage1.PerformLayout();
            this.groupBox1.ResumeLayout(false);
            this.tabPage2.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridUMDDataTypes)).EndInit();
            this.panel1.ResumeLayout(false);
            this.tabPage3.ResumeLayout(false);
            this.panel2.ResumeLayout(false);
            this.tabPage4.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridCodeValues)).EndInit();
            this.panel3.ResumeLayout(false);
            this.tabPage5.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridDBValues)).EndInit();
            this.panel4.ResumeLayout(false);
            this.tabPage7.ResumeLayout(false);
            this.tabPage6.ResumeLayout(false);
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Wizard());
        }

        private void buttonSelectInputXMI_Click(object sender, System.EventArgs e)
        {
            OpenFileDialog of = new OpenFileDialog();
            of.Title = "Select xmi file";
            of.Filter = "Xmi files (*.xmi; *.xml)|*.xmi;*.xml|All files (*.*)|*.*";
            of.FilterIndex = 0;
            if (of.ShowDialog() == DialogResult.OK)
            {
                textBoxXmiFilePath.Text = of.FileName;
            }
        }

        private bool increment;
        private void buttonNext_Click(object sender, System.EventArgs e)
        {
            increment = true;
            if (tabControl1.SelectedIndex < tabControl1.TabCount - 1)
                tabControl1.SelectedIndex += 1;
        }

        private void buttonPrev_Click(object sender, System.EventArgs e)
        {
            increment = false;
            if (tabControl1.SelectedIndex > 1)
                tabControl1.SelectedIndex -= 1;
        }

        private void tabControl1_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (stepsReady)
            {
                if (increment)
                    executeAfterStep(selectedTabIndex);

                selectedTabIndex = tabControl1.SelectedIndex;

                if (increment)
                    executeBeforeStep(selectedTabIndex);
            }
        }

        private void executeAfterStep(int i)
        {
            switch (i)
            {
                case 0:
                    {
                        if (!System.IO.File.Exists(textBoxXmiFilePath.Text))
                        {
                            MessageBox.Show("You must supply a valid xmi file !");
                            tabControl1.SelectedIndex = 0;
                        }

                        if (!System.IO.Directory.Exists(outputPath))
                        {
                            System.IO.Directory.CreateDirectory(outputPath);
                        }

                        if (radioButtonMsSql.Checked)
                            DBInput = MsSqlInput;
                        else if (radioButtonMySql.Checked)
                            DBInput = MySqlInput;

                        if (dsProject.Tables.Count == 0)
                        {
                            createDefaultXMITypeConvertion();
                        }

                        dataGridUMDDataTypes.DataSource = dsProject.Tables["XmiTypeConvertion"];
                    } break;
                case 1:
                    {
                       // wait = true;
                        try
                        {
                            string xmiXsltFile = generateXsltXmiFile(textBoxXmiFilePath.Text);
                            MakeTransformation(textBoxXmiFilePath.Text, xmiXsltFile
                                , new AsyncCallback(endMakeTransformationStep1));

                            
                        }
                        finally
                        {
                           // wait = false;
                        }
                    } break;
                case 2:
                    {
                        if (dsProject.Tables["Code"] == null)
                        {
                            createDefaultCodeValues();
                        }
                        dataGridCodeValues.DataSource = dsProject.Tables["Code"];

                    } break;
                case 3:
                    {
                        if (dsProject.Tables["DB"] == null)
                        {
                            createDefaultDBValues();
                        }
                        dataGridDBValues.DataSource = dsProject.Tables["DB"];
                    } break;
                case 4:
                    {
                    } break;
                case 5:
                    {
                        labelGenerating.Text = "Generating files";
                        labelGenerating.Refresh();
                        stepAfter5();
                        
                    } break;
            }
        }

        private void stepAfter5()
        {
            wait = true;
            System.Threading.ThreadStart ts = new System.Threading.ThreadStart(delegate()
            {
                if (checkBoxMapping.Checked)
                {
                    mappingsNode = new Node();
                    currentNode = mappingsNode;
                    foreach (Node node in xmiNode.childNodes)
                    {
                        defaultNodeName = "Mapping." + node.name;
                        string xsltMappingFile = generateXsltMappingFile(node.name);
                        MakeTransformation(node.path, xsltMappingFile);
                    }
                    SaveData(mappingsNode, false);
                }

                if (checkBoxCode.Checked)
                {
                    codeNode = new Node();
                    currentNode = codeNode;
                    foreach (Node node in xmiNode.childNodes)
                    {
                        string xsltCodeFile = generateCodeMappingFile(node.name);
                        MakeTransformation(node.path, xsltCodeFile);
                    }
                    SaveData(codeNode, true);
                }

                if (checkBoxDatabase.Checked)
                {
                    dbNode = new Node();
                    currentNode = dbNode;
                    foreach (Node node in xmiNode.childNodes)
                    {
                        string xsltDBFile = generateDataBaseMappingFile(node.name);
                        MakeTransformation(node.path, xsltDBFile);
                    }
                    SaveData(dbNode, false);
                }
                Invoke(new System.Threading.ThreadStart(delegate()
                {
                    labelGenerating.Text = "OK";
                }));
            });

            ts.BeginInvoke(new AsyncCallback(endStep5), ts);
        }

        private void endStep5(IAsyncResult res)
        {
            try
            {
                System.Threading.ThreadStart ts = (System.Threading.ThreadStart)res.AsyncState;
                ts.EndInvoke(res);
            }
            finally
            {
                wait = false;
            }
        }

        private void createDefaultCodeValues()
        {
            DataTable dt = new DataTable("Code");
            dsProject.Tables.Add(dt);

            dt.Columns.Add("type", typeof(string));
            dt.Columns.Add("value", typeof(string));

            Hashtable nvc = System.Configuration.ConfigurationManager.GetSection("defaultCodeValues") as Hashtable;

            string defaultVal = "0";
            if (nvc != null)
            {
                foreach (string k in nvc.Keys)
                {
                    if (k == "default")
                    {
                        defaultVal = nvc[k].ToString();
                    }
                    else
                    {
                        string val = nvc[k].ToString();
                        dt.Rows.Add(new object[] { k, val });
                    }
                }
            }

            foreach (Node node in xmiNode.childNodes)
            {

                XmlDocument doc = new XmlDocument();

                doc.Load(node.path);

                XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
                nsmgr.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
                nsmgr.AddNamespace("io", "urn:xmd-io");
                nsmgr.AddNamespace("typing", "urn:xmd-typing");

                foreach (XmlNode xmlnode in doc.SelectNodes("//typing:property/@type", nsmgr))
                {
                    if (dt.Select(string.Format("type='{0}'", xmlnode.Value)).Length == 0)
                        dt.Rows.Add(new object[] { xmlnode.Value, defaultVal });
                }
            }
        }

        private void createDefaultDBValues()
        {
            DataTable dt = new DataTable("DB");
            dsProject.Tables.Add(dt);

            dt.Columns.Add("type", typeof(string));
            dt.Columns.Add("value", typeof(string));

            Hashtable nvc = System.Configuration.ConfigurationManager.GetSection("defaultDBValues") as Hashtable;

            string defaultVal = "int not null default '0'";
            if (nvc != null)
            {
                foreach (string k in nvc.Keys)
                {
                    if (k == "default")
                    {
                        defaultVal = nvc[k].ToString();
                    }
                    else
                    {
                        string val = nvc[k].ToString();
                        dt.Rows.Add(new object[] { k, val });
                    }
                }
            }

            foreach (Node node in xmiNode.childNodes)
            {
                XmlDocument doc = new XmlDocument();

                doc.Load(node.path);

                XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
                nsmgr.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
                nsmgr.AddNamespace("io", "urn:xmd-io");
                nsmgr.AddNamespace("typing", "urn:xmd-typing");


                foreach (XmlNode xmlnode in doc.SelectNodes("//typing:property/@type", nsmgr))
                {
                    if (dt.Select(string.Format("type='{0}'", xmlnode.Value)).Length == 0)
                        dt.Rows.Add(new object[] { xmlnode.Value, defaultVal });
                }
            }
        }

        private void executeBeforeStep(int i)
        {
        }

        private void createDefaultXMITypeConvertion()
        {

            DataTable dt = new DataTable("XmiTypeConvertion");
            dt.Columns.Add("UMLDataType", typeof(string));
            dt.Columns.Add("value", typeof(string));

            Hashtable nvc = System.Configuration.ConfigurationManager.GetSection("defaultUMLDataType") as Hashtable;

            string defaultVal = "int not null default '0'";
            if (nvc != null)
            {
                foreach (string k in nvc.Keys)
                {
                    if (k == "default")
                        defaultVal = nvc[k].ToString();
                    else
                    {
                        string val = nvc[k].ToString();
                        dt.Rows.Add(new object[] { k, val });
                    }
                }
            }


            createDefaultXMITypeConvertionFromXMI(dt, defaultVal);

            dsProject.Tables.Add(dt);
        }

        private void createDefaultXMITypeConvertionFromXMI(DataTable dt, string defaultVal)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            bool appendAnd = false;
            foreach (DataRow dr in dt.Rows)
            {
                if (appendAnd)
                    sb.Append(" and ");
                appendAnd = true;

                sb.AppendFormat(" not({0}) ", dr[0]);
            }

            XmlDocument doc = new XmlDocument();
            doc.Load(textBoxXmiFilePath.Text);

            XmlNode xmiNode = doc.SelectSingleNode("/XMI");

            string uml = xmiNode.GetNamespaceOfPrefix("UML");
            string uml2 = xmiNode.GetNamespaceOfPrefix("UML2");

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
            if (!string.IsNullOrEmpty(uml))
                nsmgr.AddNamespace("UML", uml);
            if (!string.IsNullOrEmpty(uml2))
                nsmgr.AddNamespace("UML2", uml2);

            //UML = 'org.omg.xmi.namespace.UML' xmlns:UML2 = 'org.omg.xmi.namespace.UML2'

            string xPath = string.Concat("//UML:DataType[@name and ", sb.ToString(), "]");
            foreach (XmlElement node in doc.SelectNodes(xPath, nsmgr))
            {
                dt.Rows.Add(new object[] { string.Format("@name='{0}'", node.GetAttribute("name")), defaultVal });
            }
        }

        private Hashtable htNames = new Hashtable();

        private int _maxUID = -1;
        private int maxUID
        {
            get
            {
                if (_maxUID == -1)
                {
                    foreach (Node node in xmiNode.childNodes)
                    {
                        DataTable dt = dsProject.Tables[node.name];
                        if (dt != null)
                        {
                            if (dt.Rows.Count > 0)
                            {
                                int maxVal = (int)dt.Compute("Max(Id)", null);
                                _maxUID = Math.Max(maxVal, _maxUID);
                            }
                            else
                                _maxUID = 0;
                        }
                    }
                }
                return _maxUID;
            }
            set
            {
                _maxUID = value;
            }
        }

        private int getUniqueId(string name, string tablename)
        {
            string key = string.Concat(tablename, "|", name);
            object o = htNames[key];
            int result = 0;
            if (o != null)
                result = (int)o;
            else
            {
                maxUID = maxUID + 1;
                result = maxUID;
                htNames[key] = result;
            }

            return result;
        }

        private DataTable createDefaultMappingIds(string tableName, string pivotFileName)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            DataTable dt = dsProject.Tables[tableName];
            if (dt == null)
            {
                dt = new DataTable(tableName);
                dt.Columns.Add("ClassName", typeof(string));
                dt.Columns.Add("Id", typeof(int));
                dsProject.Tables.Add(dt);
            }


            XmlDocument doc = new XmlDocument();
            doc.Load(pivotFileName);

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
            nsmgr.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
            nsmgr.AddNamespace("io", "urn:xmd-io");
            nsmgr.AddNamespace("typing", "urn:xmd-typing");
            foreach (XmlElement node in doc.SelectNodes("//*[typing:entity]", nsmgr))
            {
                if (dt.Select(string.Concat("ClassName = '", node.Name, "'")).Length == 0)
                    dt.Rows.Add(new object[] { node.Name, getUniqueId(node.Name, tableName) });
            }

            return dt;
        }

        //private void generateXsltFiles()
        //{
        //    XsltXmiFile = generateXsltXmiFile();
        //}

        //private string XsltXmiFile;

        private string generateXsltXmiFile(string xmiPath)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(xmiPath);

            XmlNode xmiNode = doc.SelectSingleNode("/XMI");

            string uml = xmiNode.GetNamespaceOfPrefix("UML");
            string uml2 = xmiNode.GetNamespaceOfPrefix("UML2");

            System.IO.StreamReader sr = new System.IO.StreamReader(System.IO.Path.Combine(Application.StartupPath, XMIInput), System.Text.Encoding.Default, true);
            string fullDoc = sr.ReadToEnd();
            sr.Close();


            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            string[] strs = System.Text.RegularExpressions.Regex.Split(fullDoc, "(?:<UMLDataType>)");
            sb.Append(strs[0]);

            DataTable dt = dsProject.Tables["XmiTypeConvertion"];

            foreach (DataRow dr in dt.Rows)
            {
                sb.AppendFormat("<xsl:template match=\"UML:DataType[{0}]\">{1}</xsl:template>\n", dr[0], dr[1]);
            }

            strs = System.Text.RegularExpressions.Regex.Split(fullDoc, "(?:</UMLDataType>)");
            sb.Append(strs[1]);
            string result = System.IO.Path.Combine(outputPath, "XMI.xslt");
            System.IO.StreamWriter sw = System.IO.File.CreateText(result);

            fullDoc = sb.ToString();
            fullDoc = System.Text.RegularExpressions.Regex.Replace(fullDoc, 
                @"xmlns\:UML=""[^""]*""", "xmlns:UML=\"" + uml + "\"");
            fullDoc = System.Text.RegularExpressions.Regex.Replace(fullDoc,
                            @"xmlns\:UML2=""[^""]*""", "xmlns:UML2=\"" + uml2 + "\"");


            sw.Write(fullDoc);
            sw.Close();
            return result;
        }

        private string generateXsltMappingFile(string tableName)
        {
            System.IO.StreamReader sr = new System.IO.StreamReader(System.IO.Path.Combine(Application.StartupPath, MapInput), System.Text.Encoding.Default, true);
            string fullDoc = sr.ReadToEnd();
            sr.Close();

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            string[] strs = System.Text.RegularExpressions.Regex.Split(fullDoc, "<MapInput/>|<MapInput\\s/>");
            sb.Append(strs[0]);

            DataTable dt = dsProject.Tables[tableName];

            foreach (DataRow dr in dt.Rows)
            {
                //
                sb.AppendFormat("<xsl:when test=\"local-name($classNode) = '{0}'\">{1}</xsl:when>\n", dr[0], dr[1]);
            }

            sb.Append(strs[1]);
            string result = System.IO.Path.Combine(outputPath, "Mapping." + tableName + ".xslt");
            System.IO.StreamWriter sw = System.IO.File.CreateText(result);
            sw.Write(sb.ToString());
            sw.Close();
            return result;
        }

        private string getDefaultCodeValue()
        {
            Hashtable nvc = System.Configuration.ConfigurationManager.GetSection("defaultCodeValues") as Hashtable;

            if (nvc != null)
            {
                return (string)nvc["default"];
            }
            return null;
        }

        private string getDefaultDBValue()
        {
            Hashtable nvc = System.Configuration.ConfigurationManager.GetSection("defaultDBValues") as Hashtable;

            if (nvc != null)
            {
                return (string)nvc["default"];
            }
            return null;
        }

        private string generateCodeMappingFile(string tableName)
        {
            System.IO.StreamReader sr = new System.IO.StreamReader(System.IO.Path.Combine(Application.StartupPath, CSharpInput), System.Text.Encoding.Default, true);
            string fullDoc = sr.ReadToEnd();
            sr.Close();

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            string[] strs = System.Text.RegularExpressions.Regex.Split(fullDoc, "<CSharpInput/>|<CSharpInput\\s/>");
            sb.Append(strs[0]);

            DataTable dt = dsProject.Tables["Code"];

            string defaultCodeValue = getDefaultCodeValue();

            foreach (DataRow dr in dt.Rows)
            {
                sb.AppendFormat("<xsl:template match=\"@type[.='{0}']\">{1}</xsl:template>\n", dr[0], dr[1]);
            }

            if (defaultCodeValue == null)
            {
                sb.Append("<xsl:template match='@type'><xsl:message terminate='yes'>datatype <xsl:value-of select='.'/> not defined</xsl:message></xsl:template>\n");
            }
            else
            {
                sb.AppendFormat("<xsl:template match='@type'>{0}</xsl:template>\n", defaultCodeValue);
            }


            sb.Append(strs[1]);
            string result = System.IO.Path.Combine(outputPath, "CSharp." + tableName + ".xslt");
            System.IO.StreamWriter sw = System.IO.File.CreateText(result);
            sw.Write(sb.ToString());
            sw.Close();
            return result;
        }

        private string generateDataBaseMappingFile(string tableName)
        {
            System.IO.StreamReader sr = new System.IO.StreamReader(System.IO.Path.Combine(Application.StartupPath, DBInput), System.Text.Encoding.Default, true);
            string fullDoc = sr.ReadToEnd();
            sr.Close();

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            string[] strs = System.Text.RegularExpressions.Regex.Split(fullDoc, "<DBInput/>|<DBInput\\s/>");
            sb.Append(strs[0]);

            DataTable dt = dsProject.Tables["DB"];

            foreach (DataRow dr in dt.Rows)
            {
                sb.AppendFormat("<xsl:template match=\"@type[.='{0}']\"><xsl:param name=\"classId\"/>{1}</xsl:template>\n", dr[0], dr[1]);
            }

            string defaultDBValue = getDefaultDBValue();

            if (defaultDBValue == null)
            {
                sb.Append("<xsl:template match='@type'><xsl:message terminate='yes'>datatype <xsl:value-of select='.'/> not defined</xsl:message></xsl:template>\n");
            }
            else
            {
                sb.AppendFormat("<xsl:template match='@type'><xsl:param name=\"classId\"/>{0}</xsl:template>\n", defaultDBValue);
            }

            sb.Append(strs[1]);

            fullDoc = sb.ToString();

            sb = new System.Text.StringBuilder();
            strs = System.Text.RegularExpressions.Regex.Split(fullDoc, "<UUIDInput/>|<UUIDInput\\s/>");
            sb.Append(strs[0]);

            dt = dsProject.Tables[tableName];

            foreach (DataRow dr in dt.Rows)
            {
                //
                sb.AppendFormat("<xsl:when test=\"$className = '{0}'\">{1}</xsl:when>\n", dr[0], dr[1]);
            }

            sb.Append(strs[1]);

            string result = System.IO.Path.Combine(outputPath, "DBInput." + tableName + ".xslt");
            System.IO.StreamWriter sw = System.IO.File.CreateText(result);
            sw.Write(sb.ToString());
            sw.Close();
            return result;
        }

        #region IXmlWriterProvider Members

        private Node currentNode = null;
        private string defaultNodeName = "";

        XmlWriter Adoor.Metadata.IXmlWriterProvider.GetWriter(string name)
        {
            if (name == null || name == "")
                name = defaultNodeName;
            name = name.Trim();

            Adoor.Metadata.XmlRichTextBoxWriter writer = new Adoor.Metadata.XmlRichTextBoxWriter(CreateTabPage(name));
            addNode(name, writer.RichTextBox);
            return writer;
        }

        private void addNode(string nodename, RichTextBox rtb)
        {
            nodename = nodename.Trim();
            Node node = new Node();
            currentNode.childNodes.Add(node);
            node.parent = currentNode;
            node.name = nodename;
            node.path = System.IO.Path.Combine(outputPath, nodename);
            node.rtb = rtb;

        }

        #endregion

        public RichTextBox CreateTabPage(string caption)
        {
            return (RichTextBox) Invoke(new retObjectDelegate(delegate(object obj)
            {
                string Caption = (string)obj;
                TabPage tabPageResult = new System.Windows.Forms.TabPage();
                RichTextBox richTextBoxResult = new System.Windows.Forms.RichTextBox();
                // 
                // tabPageResult
                // 
                tabPageResult.AutoScroll = true;
                tabPageResult.Controls.Add(richTextBoxResult);
                tabPageResult.Location = new System.Drawing.Point(4, 22);
                tabPageResult.Name = "tabPageResult";
                tabPageResult.Size = new System.Drawing.Size(544, 359);
                tabPageResult.TabIndex = 0;
                tabPageResult.Text = Caption;
                // 
                // richTextBoxResult
                // 
                richTextBoxResult.Dock = System.Windows.Forms.DockStyle.Fill;
                richTextBoxResult.Location = new System.Drawing.Point(0, 0);
                richTextBoxResult.Name = "richTextBoxResult";
                richTextBoxResult.Size = new System.Drawing.Size(544, 359);
                richTextBoxResult.TabIndex = 0;
                richTextBoxResult.Text = "";
                // 
                // tabControl1
                // 
                results.TabControl.Controls.Add(tabPageResult);
                tabPageResult.CreateControl();
                richTextBoxResult.CreateControl();
                //Force creation of handle
                richTextBoxResult.Handle.ToInt32();
                return richTextBoxResult;
                
            }), caption);
           
        }

        public DataGrid CreateTabPageMappingIds(string Caption)
        {
            DataGrid dg = null;
            bool found = false;
            foreach (TabPage tp in tabControlMapping.TabPages)
            {
                if (tp.Text == Caption)
                {
                    found = true;
                    dg = tp.Controls[0] as DataGrid;
                    break;
                }
            }
            if (!found)
            {
                TabPage tabPageResult = new System.Windows.Forms.TabPage();
                dg = new DataGrid();
                // 
                // tabPageResult
                // 
                tabPageResult.AutoScroll = true;
                tabPageResult.Controls.Add(dg);
                tabPageResult.Location = new System.Drawing.Point(4, 22);
                tabPageResult.Name = "tabPageResult";
                tabPageResult.Size = new System.Drawing.Size(544, 359);
                tabPageResult.TabIndex = 0;
                tabPageResult.Text = Caption;
                // 
                // dg
                // 
                dg.Dock = System.Windows.Forms.DockStyle.Fill;
                // 
                // tabControl1
                // 			
                tabControlMapping.Controls.Add(tabPageResult);
            }
            return dg;
        }

        public void MakeTransformation(string xmlFile, string xslFile)
        {
            MakeTransformation(xmlFile, xslFile, null);
        }

        public void MakeTransformation(string xmlFile, string xslFile, AsyncCallback endCallback)
        {
            wait = true;                        
            makeTransformationDelegate dlg = new makeTransformationDelegate(makeTransformation);
            IAsyncResult res = dlg.BeginInvoke(xmlFile, xslFile, endCallback, dlg);
            if (endCallback == null)
            {
                try
                {
                    dlg.EndInvoke(res);
                }
                finally
                {
                    wait = false;
                }
            }
        }

        private void endMakeTransformationStep1(IAsyncResult res)
        {
            try
            {
                makeTransformationDelegate dlg = (makeTransformationDelegate)res.AsyncState;
                dlg.EndInvoke(res);

                Invoke(new System.Threading.ThreadStart(delegate()
                {
                    foreach (Node node in xmiNode.childNodes)
                    {
                        string path = System.IO.Path.Combine(outputPath, node.name);
                        StreamWriter sw = System.IO.File.CreateText(path);
                        sw.Write(node.rtb.Text);
                        sw.Close();
                        node.path = path;

                        DataTable dt = createDefaultMappingIds(node.name, path);

                        DataGrid dg = CreateTabPageMappingIds(node.name);
                        dg.DataSource = dt;
                    }
                }));
            }
            finally
            {
                wait = false;
            }
        }

        private int cnt = 0;
        private bool wait
        {
            set
            {
                if (value)
                    cnt++;
                else
                {
                    cnt = Math.Max(0, cnt - 1);
                }
                bool waitVal = cnt > 0;
                boolDelegate bd = new boolDelegate(setWaitVal);
                Invoke(bd, new object[] { waitVal });

            }
        }

        private delegate void boolDelegate(bool val);

        private void setWaitVal(bool val)
        {
            foreach(Control ctrl in Controls)
                ctrl.Enabled = !val;
            if (val)
                Cursor = Cursors.WaitCursor;
            else
                Cursor = Cursors.Default;
        }

        private delegate void makeTransformationDelegate(string xmlFile, string xslFile);

        private void makeTransformation(string xmlFile, string xslFile)
        {
            try
            {

                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(xmlFile);
                
                XslCompiledTransform xslTransform = new XslCompiledTransform(true);
                //xslTransform.Load(xslDocument/*, null, null*/);
                xslTransform.Load(xslFile);
                StringBuilder sb = new StringBuilder();

                XsltArgumentList args = new XsltArgumentList();
                XmlDocument xslDocument = new XmlDocument();
                xslDocument.Load(xslFile);
                foreach (XmlNode pi in xslDocument.SelectNodes("descendant::processing-instruction()[local-name()='arg']"))
                {
                    int pos = pi.Value.IndexOf("=");
                    if (pos == -1)
                        throw new Exception("processing instruction format error: expecting \"<?arg namespace=type ?>\"");
                    string ns = pi.Value.Substring(0, pos).Trim();
                    string typeName = pi.Value.Substring(pos + 1).Trim();
                    Type type = Type.GetType(typeName);
                    if (type == null)
                        throw new Exception("type " + typeName + " not found");
                    object arg = type.GetConstructor(new Type[] { }).Invoke(null);
                    args.AddExtensionObject(ns, arg);

                    Adoor.Metadata.IMessageProvider messageProvider = arg as Adoor.Metadata.IMessageProvider;
                    if (messageProvider != null)
                        messageProvider.LogMessage += new Adoor.Metadata.LogMessageEventHandler(messageProvider_LogMessage);

                    Adoor.Metadata.IProgress progressProvider = arg as Adoor.Metadata.IProgress;
                    if (progressProvider != null)
                        progressProvider.Progress += new Adoor.Metadata.ProgressEventHandler(progressProvider_Progress);
                }

                XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
                nsmgr.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
                nsmgr.AddNamespace("io", "urn:xmd-io");
                
                if (xslDocument.SelectSingleNode("/xsl:stylesheet/xsl:output[@method='text']", nsmgr) != null)
                {
                    xslTransform.Transform(xmlFile, args, new StringWriter(sb));
                    string result = sb.ToString();
                    RichTextBox richTextBoxResult = null;
                    //while (result != "")
                    {
                        System.Text.RegularExpressions.Regex regex = new Regex(
                            @"\-\-\-\-\s*File\:\s*(?<file>[\\_\-\.\w]+)");
                        MatchCollection matches = regex.Matches(result);
                        int start = 0;
                        string defaultfile = "Result";
                        int cnt = 0;
                        string previousfile = "Result";
                        foreach (Match match in matches)
                        {
                            string file = match.Groups["file"].Value.Trim();
                            int newStart = match.Index + match.Length;
                            string data = sb.ToString(start, match.Index - start).Trim();
                            if (data != string.Empty)
                            {
                                if (previousfile == defaultfile)
                                    previousfile = defaultfile + (++cnt).ToString();
                                richTextBoxResult = CreateTabPage(previousfile);
                                addNode(previousfile, richTextBoxResult);

                                Invoke(new System.Threading.ThreadStart(delegate()
                                {
                                    richTextBoxResult.Text = data;
                                }));
                            }
                            start = newStart;
                            previousfile = file;
                        }


                        string data2 = sb.ToString(start, sb.Length - start).Trim();
                        if (data2 != string.Empty)
                        {
                            if (previousfile == defaultfile)
                                previousfile = defaultfile + (++cnt).ToString();
                            richTextBoxResult = CreateTabPage(previousfile);
                            addNode(previousfile, richTextBoxResult);

                            Invoke(new System.Threading.ThreadStart(delegate()
                            {
                                richTextBoxResult.Text = data2;
                            }));
                        }
                        //int i = result.IndexOf("\n");
                        //string line;
                        //if (i == -1)
                        //{
                        //    line = result;
                        //    result = "";
                        //}
                        //else
                        //{
                        //    line = result.Substring(0, i + 1);
                        //    result = result.Substring(i + 1);
                        //}
                        //if (line.StartsWith("---- File: "))
                        //{
                        //    string fileName = line.Substring("---- File: ".Length).Trim();

                        //    //if (fileName.EndsWith("\n"))
                        //    //    fileName = fileName.Substring(0, fileName.Length - 1);
                        //    richTextBoxResult = CreateTabPage(fileName);
                        //    addNode(fileName, richTextBoxResult);
                        //    continue;
                        //}

                        //if (richTextBoxResult == null)
                        //{
                        //    idx++;
                        //    richTextBoxResult = CreateTabPage("Result");
                        //    addNode("Result" + idx, richTextBoxResult);
                        //}
                        //Invoke(new System.Threading.ThreadStart(delegate()
                        //{
                        //    richTextBoxResult.Text += line;
                        //}));
                    }
                }
                else
                {

                    XmlWriter xmlWriter = new Adoor.Metadata.XmlMultiFileWriter(this);
                    //xslTransform.Transform(xmlDocument, args, xmlWriter/*, null*/);
                    xslTransform.Transform(xmlFile, args, xmlWriter);
                }
            }
            catch (Exception exx)
            {
                Invoke(new objectDelegate(delegate(object obj)
                {
                    Exception ex = (Exception)obj;
                    MessageBox.Show(string.Concat(xmlFile, System.Environment.NewLine, "+ ", xslFile, System.Environment.NewLine, ex.StackTrace));
                    while (ex != null)
                    {
                        MessageBox.Show(ex.Message);
                        ex = ex.InnerException;
                    }
                }), exx);
            }
            finally
            {
            }
        }

        private delegate void objectDelegate(object obj);
        private delegate object retObjectDelegate(object obj);

        public class Node
        {
            public RichTextBox rtb;
            public Node parent;
            public ArrayList childNodes = new ArrayList();
            public string name;
            public string path;
        }

        public void SaveData(Node node, bool merge)
        {
            ArrayList notGeneratedFiles = new ArrayList(node.childNodes.Count);

            foreach (Node childNode in node.childNodes)
            {
                string fileName = childNode.path;
                fileName = fileName.Replace(".DataAccess.DataAccess", ".DataAccess");

                fileName = System.IO.Path.Combine(outputPath, fileName);
                System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(fileName));

                Invoke(new System.Threading.ThreadStart(delegate()
                {
                    statusBar1.Text = string.Concat("Saving ", fileName);
                }));

                Invoke(new System.Threading.ThreadStart(delegate()
                {
                    RichTextBox richTextBox = childNode.rtb;
                    try
                    {
                        if (merge && System.IO.File.Exists(fileName))
                            MergeData(richTextBox.Text, fileName);
                        else
                        {
                            System.IO.StreamWriter sw = new StreamWriter(fileName, false, Encoding.Default);
                            sw.Write(richTextBox.Text);
                            sw.Close();
                        }
                    }
                    catch (System.UnauthorizedAccessException)
                    {
                        notGeneratedFiles.Add(fileName);
                    }
                }));
            }

            if (notGeneratedFiles.Count != 0)
            {
                System.Text.StringBuilder sb = new StringBuilder();
                foreach (string s in notGeneratedFiles)
                    sb.AppendFormat("{0}\n", s);

                Invoke(new System.Threading.ThreadStart(delegate()
                {
                    MessageBox.Show(null,
                        string.Concat("Generation failed for the folowing files : \n", sb.ToString()),
                        "Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }));
            }
        }

        public void MergeData(string text, string fileName)
        {
            Invoke(new System.Threading.ThreadStart(delegate()
            {
                statusBar1.Text = string.Concat("Merging ", fileName);
            }));
            FileStream fs = File.OpenRead(fileName);
            StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default, true);
            string existingFile = sr.ReadToEnd();
            string newFile = text;

            Regex regexExisting = new Regex(
                @"(?<region>\#region\s(?<def>user\scode\s[^\n]*))",
                RegexOptions.IgnoreCase | RegexOptions.Multiline
                | RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture
                | RegexOptions.Compiled);

            MatchCollection matchFcts = regexExisting.Matches(existingFile);
            foreach (Match match in matchFcts)
            {
                string def = match.Groups["def"].Value;
                string endRegion = string.Concat("#endregion ", def).Trim();
                def = Regex.Escape(def.Trim());
                int endExisting = existingFile.IndexOf(endRegion, match.Index);
                if (endExisting >= 0)
                {
                    Regex regexNewFile = new Regex(
                        string.Concat(@"(?<region>\#region\s", def, ")",
                        @"(?<code>[^#]*)(?<endregion-region>\#endregion\s", def, @"(?<endspace>\s))"),
                        RegexOptions.IgnoreCase | RegexOptions.Multiline
                        | RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture
                        | RegexOptions.Compiled);
                    newFile = regexNewFile.Replace(newFile, string.Concat(existingFile.Substring(match.Index, endExisting + endRegion.Length - match.Index), "${endspace}"));
                }
            }
            sr.Close();
            fs.Close();
            StreamWriter sw = new StreamWriter(fileName, false, System.Text.Encoding.Default);
            sw.Write(newFile);
            sw.Close();
        }

        private static string ExtractFilePath(string fileName)
        {
            int pos = fileName.LastIndexOf("\\");
            if (pos == -1)
                return "";
            return fileName.Substring(0, pos);
        }

        private static void ForceDirectory(string fileName)
        {
            if (fileName == "")
                return;
            System.IO.Directory.CreateDirectory(fileName);
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            results.Show();
        }

        private void buttonSave_Click(object sender, System.EventArgs e)
        {
            save();
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            switch (MessageBox.Show("Save project ?", "", MessageBoxButtons.YesNoCancel))
            {

                case DialogResult.Cancel:
                    e.Cancel = true;
                    break;
                case DialogResult.Yes:
                    save();
                    break;
            }
            base.OnClosing(e);
        }

        private void save()
        {
            SaveFileDialog sd = new SaveFileDialog();
            sd.Title = "Save project";
            sd.DefaultExt = ".adoorwzd";
            sd.Filter = "Adoor project wizard (*.adoorwzd)|*.adoorwzd";
            if (sd.ShowDialog() == DialogResult.OK)
            {
                Hashtable htSave = new Hashtable();
                htSave["Dataset"] = dsProject;
                htSave["input"] = textBoxXmiFilePath.Text;
                htSave["output"] = outputPath;
                htSave["MsSql"] = radioButtonMsSql.Checked;
                htSave["MySql"] = radioButtonMySql.Checked;
                htSave["GenerateCode"] = checkBoxCode.Checked;
                htSave["GenerateDB"] = checkBoxDatabase.Checked;
                htSave["GenerateMapping"] = checkBoxMapping.Checked;

                System.Runtime.Serialization.Formatters.Soap.SoapFormatter sf = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
                FileStream fs = System.IO.File.OpenWrite(sd.FileName);
                sf.Serialize(fs, htSave);
                fs.Close();
            }
        }

        private void buttonChooseOutput_Click(object sender, System.EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                textBoxOutput.Text = fbd.SelectedPath;
            }
        }

        private void textBoxOutput_TextChanged(object sender, System.EventArgs e)
        {
            outputPath = textBoxOutput.Text;
        }

        private void buttonLoadProject_Click(object sender, System.EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "Open project";
            ofd.DefaultExt = ".adoorwzd";
            ofd.Filter = "Adoor project wizard (*.adoorwzd)|*.adoorwzd";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                System.Runtime.Serialization.Formatters.Soap.SoapFormatter sf = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
                FileStream fs = System.IO.File.OpenRead(ofd.FileName);
                Hashtable htProject = sf.Deserialize(fs) as Hashtable;
                fs.Close();

                dsProject = htProject["DataSet"] as DataSet;
                textBoxXmiFilePath.Text = (string)htProject["input"];
                textBoxOutput.Text = (string)htProject["output"];
                radioButtonMsSql.Checked = (bool)htProject["MsSql"];
                radioButtonMySql.Checked = (bool)htProject["MySql"];
                if (htProject.Contains("GenerateCode"))
                    checkBoxCode.Checked = (bool)htProject[""];
                if (htProject.Contains("GenerateDB"))
                    checkBoxDatabase.Checked = (bool)htProject["GenerateDB"];
                if (htProject.Contains("GenerateMapping"))
                    checkBoxMapping.Checked = (bool)htProject["GenerateMapping"];
            }
        }

        private void buttonExit_Click(object sender, System.EventArgs e)
        {
            Close();
        }

        private void buttonUpdateIds_Click(object sender, System.EventArgs e)
        {
            foreach (Node node in xmiNode.childNodes)
            {
                string path = System.IO.Path.Combine(outputPath, node.name);
                StreamWriter sw = System.IO.File.CreateText(path);
                sw.Write(node.rtb.Text);
                sw.Close();
                node.path = path;

                DataTable dt = createDefaultMappingIds(node.name, path);

                DataGrid dg = CreateTabPageMappingIds(node.name);
                dg.DataSource = dt;
            }
        }

        private void messageProvider_LogMessage(object sender, Adoor.Metadata.LogMessageEventArgs e)
        {
            Invoke(new objectDelegate(delegate(object obj)
            {
                statusBar1.Text = (string)obj;
            }), e.Message);            
        }

        private void progressProvider_Progress(object sender, Adoor.Metadata.ProgressEventArgs evt)
        {
            Invoke(new objectDelegate(delegate(object obj)
           {
               Adoor.Metadata.ProgressEventArgs e = (Adoor.Metadata.ProgressEventArgs)obj;
               pgBar.Minimum = 0;
               pgBar.Maximum = e.Total;
               pgBar.Value = e.Current;
               pgBar.Refresh();
           }), evt);
        }
    }
}